home *** CD-ROM | disk | FTP | other *** search
- /*
- HASUtilPStrings.c from Hsoi's App Shell ©1995-1997 John C. Daub. All rights reserved.
-
- This file is a collection of various functions that allow you to deal with Pascal
- type strings (since using ANSI C library functions, like strcpy just can't work
- that well on Pascal strings...which is what the MacOS uses).
-
- So you know, there are also some C-glue functions that you can use...
- these functions allow you to use C style strings instead of Pascal style
- strings when calling toolbox routines. to use these C-glue functions,
- first you have to know if your compiler supports it. For more information
- about it, you can check the ConditionalMacros.h file and look for this
- symbol: CGLUESUPPORTED. If you'd like to be lazy, from what ConditionalMacros.h
- says, it seems that only THINK C cannot support the C-glue functions.
-
- To find the functions you can use, you can just enter the CGLUESUPPORTED into
- your Find dialog and search through all your Universal Header files. That'll
- turn you up a lot of information.
-
- Also, you'll need to make sure you have a C-glue library in your project. In
- Metrowerks CodeWarrior (which is what I use) there is a file called CGlue.c
- in the MacOS Support:Libraries:MacOS 68k:MacOS Files folder. You'll need this
- (I assume) to use these functions. However, I didn't find a PPC version of
- the CGlue.c file...i don't know if you can just use the same CGlue.c file
- in PPC projects or not, or even if CGlue is supported on PowerMacs....honestly,
- I don't use this stuff, so I've not tried...give it a whirl if you care to
- try and let me know how it turns out! :)
-
- Also, there's a file called PLStringFuncs.h. Never used it nor the stuff
- within it, but it's a C string conversion for Pascal file. Give it some
- investigation if you'd like (and don't forget to add in the proper
- libs for 68k and PPC for using the PLStringFuncs)...it might be useful.
-
- But in the end, I just like using what I have here...they're quick, simple
- and easy, and no need to have to link in external libraries just to use
- one or two functions.
- */
-
- #pragma mark ••• #includes •••
-
- #include "HASUtilPStrings.h"
-
- #pragma mark -
- #pragma mark ••• HAS String Functions •••
-
- /* pStringCopy: copy one Pascal string to another */
-
- void HsoipStringCopy( ConstStr255Param srcString, Str255 destString )
- {
- register short index;
-
- index = srcString[0] + 1;
-
- while( index-- )
- {
- *destString++ = *srcString++;
- }
-
- return;
- }
-
- /*
- ConcatString: concatenate two Pascal strings. s2 will be tacked onto
- the end of s1 (s1 will now be modified and contain the whole thing, s2
- will be "unchanged"
- */
-
- void HsoiConcatString( Str255 s1, Str255 s2 )
- {
- register unsigned char index1, index2;
-
- if ( s2[ 0 ] == 0 )
- return;
-
- if ( ( (short)s1[0] + (short)s2[0] ) > 255 )
- return;
-
- for ( index1 = s1[0] + 1, index2 = 1; index2 <= s2[ 0 ]; index1++, index2++ )
- {
- s1[ index1 ] = s2[ index2 ];
- }
-
- s1[0] += s2[0];
-
- return;
- }
-
- // HsoiStripDecimal is sorta an obsolete function. i was using it at one
- // time in HAS as i was porting some Pascal functions to C (combinations of
- // the pascal functions pos with insert and delete). However, with the way
- // things turned out, this function became unnecessary, however i still felt
- // like keeping it around just to show you another example and fun with
- // manipulating strings.
-
- // what this does is strip the decimal point out of a given string (srcStr)
- // and returns the stripped string (strippedStr). for example, if you have
- // 1.3, you'll return 13. if you have 123.456, you'll get 123456. if
- // 123, 123. get it? it's probably not that useful ouside of what it was
- // originally written for (doubt it has much worth outside of that), but it's
- // cute to look at at least.
-
- void HsoiStripDecimal( ConstStr255Param srcStr, Str255 strippedStr )
- {
- register short i, j;
- Boolean srcHasDecimal = false; // assume it won't
-
- // first, we make sure there even is a decimal point in the strStr to strip.
- // if there isn't, makes our life easier :)
-
- for ( i = 1; i <= 255; i++ )
- {
- if ( srcStr[i] == '.' )
- {
- srcHasDecimal = true;
- break; // might as well can out
- }
- }
-
- // if there is no decimal, we'll just copy srcStr into strippedStr...simple
-
- if ( !srcHasDecimal )
- {
- HsoipStringCopy( srcStr, strippedStr );
- return; // and we can go home
- }
-
- // here's the fun...if there is a decimal (and we'll only assume the first period
- // in the string...if there are mor periods in the string, oh well....) we'll have
- // a little fun manipulating things.
-
- // first, just straight copy over from srcStr to strippedStr until we hit the decimal
- // (nicely enough, "i" holds the "exact location" of where the decimal is)
-
- for ( j = 1; j < i; j++ )
- strippedStr[j] = srcStr[j];
-
- // and now we skip over the decimal and continue copying until we're done
-
- for ( j = i + 1; j <= srcStr[0]; j++ )
- strippedStr[j - 1] = srcStr[j];
-
- // and finally, the Pascal string needs a length byte
-
- strippedStr[0] = srcStr[0] - 1;
-
-
- return;
- }
-
- // HsoipCopy is a port of the MyCopy function from Tom Bender's Text-Edit+ 1.6.3
- // says Tom: this function is used to replace the standard MW copy function because the
- // MW function returns a null string if start or count are out of range. This function
- // pins the start or count to allowable values.
- // the original Pascal prototype looked like this:
- // function MyCopy( source: string; start, cout: integer): string;
- // i've obviously modifed this slightly
-
- void HsoipCopy( Str255 src, short start, short count, Str255 dest )
- {
- // pin start to allowable value
-
- if ( start < 1 )
- {
- count -= (1 - start);
- start = 1;
- }
-
- // pin count to allowable values
-
- if ( (start + count) > src[0] )
- count = src[0] - start + 1;
- if ( count < 0 )
- count = 0;
-
- // now do the actual copy
-
- src[0] = count;
- BlockMoveData( &src[start], &src[1], count );
- HsoipStringCopy( src, dest );
-
- return;
- }
-
- #pragma mark -
- #pragma mark ••• Pascal Operator Functions (In C) •••
-
- /*
- what follows are a bunch of C ports of a lot of common Pascal operator functions.
- they're not used everywhere in HAS, but included here cause someday you might
- find them useful and handy. besides, so much of the MacOS was originally
- done in Pascal, these probably will be useful to you in someway.
-
- i acquired them from Ken Long (kenlong@netcom.com), who's always been a kind,
- helpful person to the Mac programming community. Thanx Ken! Oh, and as for
- who wrote these, Ken told me that it wasn't him that wrote them, but
- someone with the initials of SKA (apparently this person was porting some
- Pascal code, i think Tom Bender's Tex-Edit code ironicly enough, and
- wrote these...Ken acquired them when he got a copy of a C port of Tex-Edit).
- Hopefully no one will mind me using them here.
-
- usage of these functions should be pretty self-explanitory. if not, try
- looking them up in any Pascal language reference (for example, the QuickView
- database that came with CW7). it'll be the same deal.
-
- and tho the rest of HAS uses the "HsoiXxx" naming convention for functions,
- due to these being really Pascal functions, i'm leaving their names as is
- to make it easier.
- */
-
- // utils.c
- // Added by SKA for misc utility functions
- // All strings are assumed Pascal strings (with length in first byte)
- // No error checking is done for string overflow beyond 255 chars
-
- Boolean isAlpha(char ch)
- {
- return ('A' <= ch && ch <= 'Z' || 'a' <= ch && ch <= 'z');
- }
-
- Boolean isLower(char ch)
- {
- return ('a' <= ch && ch <= 'z');
- }
-
- Boolean isUpper(char ch)
- {
- return ('A' <= ch && ch <= 'Z');
- }
- // if you're curious what some of these numbers are in these functions, check
- // your handy ASCII character chart...these are the decimal equivalents of these
- // unprintable characters (fyi, THINK Reference has an ASCII chart in it)
-
- Boolean isSeparator(char ch)
- {
- /* I will try to translate this down for those without an ASCII chart.
- all numeric values (both in the translation and the code) are in decimal
- (not hex or octal)
-
- if the character is a non-printable control character (31 or less) or
- one of these: 'space' ! " # $ % & ' ( ) * + , - . / (47 or less) OR
- the char is greater than or equal to a : (between 48 and 57 inclusive
- are the digits 0-9) AND less than a ? (: ; < = > ? are 58-63) OR
- between 91 and 95 inclusive ([ \ ] ^ _) OR is { OR | or } or between
- 208 and 212 (these are unprintable here, but 208 and 209 i dunno what
- they are, 210 is the left smart quote, 211 is the right smart quote, and
- 212 is the smart apostrophe)
-
- then return true :)
-
- basically, anything not a "letter" will return true, letters return false.
-
- but, this can greatly vary (actually) depending on how the font is set up.
- the ASCII standards (below 128) will be for sure, but who knows what anything
- in the non-standard set will return since there are a lot of non-character
- things abover 128 that should return true, but again can vary from font to font.
- */
- return (ch < 48 || 58 <= ch && ch <= 63 || 91 <= ch && ch <= 95 ||
- ch == 123 || ch == 124 || ch == 125 || 208 <= ch && ch <= 212);
- }
-
- Boolean isNonquoteSeparator(char ch)
- {
- return (ch != '\'' && isSeparator(ch));
- }
-
- Boolean isSentenceEnder(char ch)
- {
- return (ch == '\t' || ch == 12 || ch == '\r' || ch == ' ' || ch == '!' ||
- ch == '.' || ch == '?' || ch == 201);
- }
-
- Boolean isSentenceStarter(char ch)
- {
- return (ch == '\t' || ch == '\r' || ch == ' ');
- }
-
- char UprChar(char ch, Boolean diac)
- {
- Str255 s;
-
- s[0] = 1; s[1] = ch;
- UpperString(s, diac);
- return s[1];
- }
-
- // returns position of 1st occurrence of ch in str, 0 if none
- short charPos(char ch, Str255 str)
- {
- register short i, lstr;
-
- lstr = *str++;
- for (i = 1; i <= lstr && str[i] != ch; i++)
- ;
- return (i <= lstr ? i : 0);
- }
-
- // returns position of 1st occurrence of pat in str, 0 if none
- short pos(Str255 pat, Str255 str)
- {
- register short i, j, k, lstr, lpat;
-
- lstr = *str; lpat = *pat;
- for (i = 1; i <= lstr; i++) {
- for (j = i, k = 1; k <= lpat && str[j] == pat[k]; j++, k++)
- ;
- if (k > lpat)
- return i;
- }
- return 0;
- }
-
- void copyStr (Str255 dest, Str255 src)
- {
- register short len;
-
- len = src[0];
- while (len-- >= 0) *dest++ = *src++;
- }
-
- void copySubStr (Str255 dest, Str255 src, short first, short len)
- {
- unsigned char *src1;
-
- *dest++ = (unsigned char) len;
- src1 = src+first;
- while (len--) *dest++ = *src1++;
- }
-
- void concat(Str255 dest, Str255 str1, Str255 str2)
- {
-
- register short len;
-
- *dest++ = (len = *str1++) + *str2;
- while (len--) *dest++ = *str1++;
- len = *str2++;
- while (len--) *dest++ = *str2++;
- }
-
- void insert(Str255 str, Str255 src, short i)
- {
- register short j, p, q, lstr, lsrc;
-
- lstr = str[0]; lsrc = src[0];
- lsrc += lstr;
- if (lstr+lsrc <= 255) {
- for (p = lsrc, q = lsrc-lstr; q >= i; p--, q--)
- str[p] = str[q];
- for (j = 0, p = i, q = 1; j < lsrc; j++)
- str[p++] = src[q++];
- }
- }
-
- void append(Str255 dest, Str255 str)
- {
- register short i, j, len;
-
- len = str[0];
- i = dest[0]+1;
- for (i = dest[0]+1, j = 1; j <= len; i++, j++)
- dest[i] = str[j];
- dest[0] += len;
- }
-
- // originally, this function was called "delete" (as is the pascal function of the
- // same name). however, "delete" is also a reserved keyword in certain languages
- // (like C++) and could pose some compiler errors. Due to this fact, this function
- // has been renamed "pDelete" (for "Pascal delete")
-
- void pDelete(Str255 str, short i, short len)
- {
- register short j, k, lstr;
-
- lstr = str[0];
- if (i <= lstr && lstr >= i+len-1) {
- str[0] = lstr - len;
- for (j = 0, k = i+len; j < len; j++, i++, k++)
- str[i] = str[k];
- }
- }
-
- OSType packString(Str255 str)
- {
- OSType a;
-
- a = ((long) str[1] << 24) | ((long) str[2] << 16) | (str[3] << 8) | str[4];
- return a;
- }
-
- void unpackOSType(OSType a, Str255 str)
- {
- long mask = 0xFF;
-
- str[0] = 4;
- str[1] = a >> 24;
- str[2] = (a >> 16) & mask;
- str[3] = (a >> 8) & mask;
- str[4] = a & mask;
- }
-